package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
@Transactional
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("为申请单生成对应的审批单业务，参数：{}", application);
        //1.遍历申请中的审批人集合，有几个审批人，就生成几条审批数据
        List<Long> userIdList = application.getAuditUserIdList();
        for (int i = 0; i < userIdList.size(); i++) {
            Audit audit = new Audit();
            //2.设置申请单id
            audit.setApplicationId(application.getId());
            //3.设置审批人id
            audit.setAuditUserId(userIdList.get(i));
            //4.设置审批次序
            audit.setAuditSort(i);
            //5.设置审批状态
            if (i == 0) {
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            } else {
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            //6.设置新增时间
            audit.setCreateTime(new Date());
            //7.调用数据层，新增审批数据
            auditMapper.insert(audit);
        }

    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        return auditMapper.selectAuditByApplicationId(id);
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单的业务，参数：{}", auditQuery);
        List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
        for (int i = 0; i < auditVOList.size(); i++) {
            AuditVO auditVO = auditVOList.get(i);
            assginAuditUserList(auditVO);
        }
        return auditVOList;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批单的业务，参数：{}", auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam, audit);
        audit.setUpdateTime(new Date());
        //除了要更新审批单以外，还需要更新申请单
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        //接下来的操作需要判断是“通过”还是“驳回”
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())) {//通过
            //更新当前的这条审批单
            auditMapper.update(audit);
            /* 需要查当前审批单对应的申请单下是否有未审核的数据 */
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id+审批状态，查出此申请单是否有为审批的数据
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            if (count > 0) {//还有未审批的数据
                auditQuery.setAuditSort(audit.getAuditSort() + 1);
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                if (auditVOList != null && auditVOList.size() > 0) {
                    AuditVO auditVO = auditVOList.get(0);
                    //准备第2个审批单对象用作更新
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    auditMapper.update(audit2);
                }
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            } else {//没有未审批的数据，我是最后一个审批人
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        } else if (audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())) {//驳回
            //更新当前审批单
            auditMapper.update(audit);//10-->40
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查出来所有的审批单
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            if (auditVOList != null && auditVOList.size() > 0) {
                for (int i = 0; i < auditVOList.size(); i++) {
                    AuditVO auditVO = auditVOList.get(i);
                    //如果出现状态是“待他人审核”的审批单，无需审批了，直接删除
                    if(auditVO.getAuditStatus().equals(AuditStatusEnum.PENDING.getCode())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            //设置申请单的状态为“驳回”，并设置驳回原因，更新申请单
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    private void assginAuditUserList(AuditVO auditVO) {
        //1.准备空集合，用来保存审批人姓名与id
        List<String> auditUsernameList = new ArrayList<>();
        List<Long> auditUserIdList = new ArrayList<>();
        //2.根据传入的申请单id，查询当前申请单对应的审批数据，注意：一个申请可能对应多个审批！
        List<AuditVO> auditVOList =
                auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //3.依次遍历每个审批单对象
        for (int i = 0; i < auditVOList.size(); i++) {
            //4.获取当前审批单对象中的审批人id,存入上方的空集合中
            Long id = auditVOList.get(i).getAuditUserId();
            auditUserIdList.add(id);
            //5.根据审批人id,查出此人姓名，并存入上方的空集合中
            UserVO userVO = userMapper.selectById(id);
            auditUsernameList.add(userVO.getUsername());
        }
        //6.准备一个字符串拼接工具
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList) {
            stringJoiner.add(username);
        }
        //7.将查出的审批人id赋值给传入的auditVO的auditUserIdList属性
        auditVO.setAuditUserIdList(auditUserIdList);
        //8.将转为字符串的审批人姓名字符串，赋值给传入的auditVO的auditUsernameList属性
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }
}
